﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace UnitTests
{

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System.IO;
    using System;

    namespace TestSpltMergeFiles
    {
        [TestClass()]
        public class SplitAndEncryptTest
        {
            private static string FILENAME = @"D:\Downloads\Games\UNI\Telerik\NetEssentials\Elian Kurtenkov\SampleIntermediateExam_1\Split_MergeBinFiles\bin\Debug\Test.mp3";
            public const int ONE_MB = 1024 * 1024;

            private TestContext testContextInstance;
            public TestContext TestContext
            {
                get
                {
                    return testContextInstance;
                }
                set
                {
                    testContextInstance = value;
                }
            }

            private string[] GetSplittedFilesNames(string filename)
            {
                string newFilePart1 = string.Format("{0}-part_1.{1}", filename.Split('.')[0], filename.Split('.')[1]);
                string newFilePart2 = string.Format("{0}-part_2.{1}", filename.Split('.')[0], filename.Split('.')[1]);
                return new string[] { newFilePart1, newFilePart2 };
            }

            private string GetProductFileName(string orig_fileName)
            {
                string[] nameParts = orig_fileName.Split('.');
                string outputFilename = string.Format("{0}-original.{1}", nameParts[0], nameParts[1]);
                return outputFilename;
            }

            [TestMethod()]
            public void SplitFilesExistTest()
            {
                string fileName = FILENAME;
                SplitAndMerge.SplitFile(fileName);
                string[] newFilenames = GetSplittedFilesNames(fileName);
                Assert.IsTrue(File.Exists(newFilenames[0]) && File.Exists(newFilenames[1]));
            }

            [TestMethod()]
            public void SplitFilesSizeTest()
            {
                string fileName = FILENAME;
                SplitAndMerge.SplitFile(fileName);
                string[] newFilenames = GetSplittedFilesNames(fileName);
                long file1_size, file2_size, original_file_zize;
                original_file_zize = (new FileInfo(fileName)).Length;
                file1_size = (new FileInfo(newFilenames[0])).Length;
                file2_size = (new FileInfo(newFilenames[1])).Length;
                bool fileSizezAreCorrect = file1_size + file2_size == original_file_zize &&
                    (Math.Abs(file2_size - file1_size) <= 1);
                Assert.IsTrue(fileSizezAreCorrect);

            }

            [TestMethod()]
            public void MergedFileExistTest()
            {
                string fileName = FILENAME;
                SplitAndMerge.MergeFilesToOriginal(fileName);
                string product_fileName = GetProductFileName(fileName);
                Assert.IsTrue(File.Exists(product_fileName));
            }

            [TestMethod()]
            public void MergedFileSizeTest()
            {
                string fileName = FILENAME;
                SplitAndMerge.MergeFilesToOriginal(fileName);
                string product_fileName = GetProductFileName(fileName);
                long original_file_size = (new FileInfo(fileName)).Length;
                long product_file_size = (new FileInfo(product_fileName)).Length;
                Assert.AreEqual(original_file_size, product_file_size);
            }

            [TestMethod()]
            public void MergedFileEqualsOriginalTest()
            {
                bool areEqual = true;
                string fileName = FILENAME;
                SplitAndMerge.MergeFilesToOriginal(fileName);
                string product_fileName = GetProductFileName(fileName);
                using (FileStream readStream_orig = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    using (FileStream readStream_product = new FileStream(product_fileName, FileMode.Open, FileAccess.Read))
                    {
                        byte[] orig_buffer = new byte[ONE_MB];
                        byte[] product_buffer = new byte[ONE_MB];
                        while (true)
                        {
                            int bytesRead = readStream_orig.Read(orig_buffer, 0, ONE_MB);
                            if (bytesRead == 0)
                            {
                                break;
                            }
                            readStream_product.Read(product_buffer, 0, ONE_MB);
                            for (int i = 0; i < bytesRead; i++)
                            {
                                if (orig_buffer[i] != product_buffer[i])
                                {
                                    areEqual = false;
                                    break;
                                }
                            }
                        }
                    }
                }
                Assert.IsTrue(areEqual);
            }

        }
    }

}
